package com.golxen.framework.common.server.game.cmd;

import com.golxen.utils.LogUtil;
import com.golxen.utils.ScanUtils;
import com.mysql.cj.util.LogUtils;
import org.slf4j.Logger;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * 命令集
 */
public final class CommandSet {

	private static Logger logger = LogUtil.COMMON;

	private static final Map<Integer, Class<?>> cmdCache = new HashMap<>();

	static boolean init = false;

	private CommandSet() {
	}

	public static boolean load() {
		try {
			if (init) {
				return true;
			}
			if (!checkCommand()) {
				return false;
			}

			scan("com.golxen");

			logger.info("cmdCache size : " + cmdCache.size());
			init = true;
			return true;
		} catch (Exception e) {
			logger.error("load command error:", e);
			return false;
		}
	}

	private static void scan(String path) throws ClassNotFoundException, IOException {
		Set<Class<?>> allClasses = ScanUtils.scanClass(path);

		for (Class<?> clazz : allClasses) {
			try {
				Cmd cmd = clazz.getAnnotation(Cmd.class);
				if (cmd != null) {
					if (cmdCache.get(cmd.code()) != null) {
						String name = cmdCache.get(cmd.code()).getClass().getName();
						logger.error("cmd code error, code : 0x" + Integer.toHexString(cmd.code()).toUpperCase()
								+ " exist :" + name + ", new : " + clazz.getName());
						System.exit(1);
					}
					cmdCache.put(cmd.code(), clazz);
				}

			} catch (Exception e) {
				logger.error("load command fail, command name : " + clazz.getName(), e);
				logger.error("load command exception:", e);
			}
		}
	}

	public static Command getCommand(int code) {
		try {
			return (Command) cmdCache.get(code).newInstance();
		} catch (Exception e) {
			logger.error("异常错误, code: {}", code, e);
			return null;
		}
	}

	private static boolean checkCommand() {
		try {

		} catch (Exception e) {
			logger.error("checkCommand error:", e);
			return false;
		}
		return true;
	}
}
